Skip to content

Distinguish HEY World posts from email - #185

Open
code-monger-givenall wants to merge 4 commits into
basecamp:mainfrom
code-monger-givenall:agent/world-post-safety
Open

Distinguish HEY World posts from email#185
code-monger-givenall wants to merge 4 commits into
basecamp:mainfrom
code-monger-givenall:agent/world-post-safety

Conversation

@code-monger-givenall

@code-monger-givenall code-monger-givenall commented Aug 19, 2026

Copy link
Copy Markdown

What changed

HEY box responses can mix email topics with published HEY World posts. The CLI treated every item as an email, which made counts misleading and made email actions look valid for published content.

This change:

  • preserves each item kind in CLI and TUI models
  • reports total items, email count, and HEY World post count in JSON metadata
  • summarizes mixed boxes as, for example, 2,944 emails and 21 HEY World posts
  • adds --kind to email organization commands and rejects world/post before authentication or any HTTP request
  • blocks thread opening, moving, Trash, Spam, and ignore actions for World posts in the TUI
  • adds a separate hey world delete <token> --confirm command using the SDK World endpoint

Existing command calls without --kind remain compatible. Callers that read from hey box --json should pass the returned kind so the CLI can enforce the boundary. The TUI already has that context and enforces it automatically.

World deletion requires the post token, not the box item ID, and explicit confirmation. No existing HEY World posts were deleted while developing or testing this change.

Tests

  • make check
  • mixed email and World post counts and JSON metadata
  • all seven email-only CLI actions reject world/post without making a request
  • TUI email actions reject World posts without making a request
  • World deletion requires confirmation and uses /world/posts/{token}, never /postings/trash

Summary by cubic

Distinguishes HEY World posts from email, separates box item IDs from email topic IDs, and blocks email actions on published content. Previously every box item was treated as email and IDs were conflated; now the CLI/TUI preserve kind, show accurate counts, and route HEY World deletions through a dedicated command.

  • hey box preserves per-item kind, shows Item/Kind/Topic columns (World posts have no Topic), prints mixed summaries (e.g., “2,944 emails and 21 HEY World posts”), and adds JSON metadata: posting_count, email_count, world_post_count.
  • Email actions (seen, unseen, move, trash, spam, ignore, stop-ignoring) accept --kind, act on box id (not topic_id), and reject world/post locally before auth or any request.
  • TUI blocks open/move/trash/spam/ignore on world/post, shows a notice, and makes no requests.
  • Adds hey world delete <token> --confirm using /world/posts/{token} (separate from email Trash); help includes a new HEY WORLD section and updates email action examples to include --kind topic.

Migration

  • Existing calls remain compatible without --kind. If you parse hey box --json, pass id + --kind topic for email actions and use topic_id for reading/replying/forwarding; do not assume id == topic_id.
  • Email actions on world/post now fail locally with guidance and make no requests.
  • To remove a HEY World post, use hey world delete <token> --confirm with the post token (not the box item ID).

Written for commit 934ce67. Summary will update on new commits.

Review in cubic

Copilot AI balanced review requested due to automatic review settings August 19, 2026 18:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Distinguishes HEY World posts from email across the CLI and TUI, preventing inappropriate email actions and adding a dedicated deletion command.

Changes:

  • Preserves posting kinds and reports separate email and World-post counts.
  • Blocks email-only actions for world/post items.
  • Adds confirmed HEY World deletion through the SDK.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.surface Registers new commands and flags.
API-COVERAGE.md Documents the World deletion endpoint.
README.md Documents posting kinds and World deletion.
skills/hey/SKILL.md Adds agent guidance for World posts.
internal/cmd/box.go Counts and summarizes posting kinds.
internal/cmd/box_test.go Tests mixed-kind JSON output and counts.
internal/cmd/help.go Adds World commands to help.
internal/cmd/help_test.go Updates help expectations.
internal/cmd/ignore.go Adds World-post validation.
internal/cmd/move.go Adds World-post validation.
internal/cmd/posting_kind.go Implements shared kind validation.
internal/cmd/posting_kind_test.go Tests rejection across email actions.
internal/cmd/root.go Registers the World command.
internal/cmd/seen.go Adds validation to seen/unseen.
internal/cmd/spam.go Adds World-post validation.
internal/cmd/stop_ignoring.go Adds World-post validation.
internal/cmd/trash.go Adds World-post validation.
internal/cmd/trash_test.go Tests trash/spam rejection.
internal/cmd/world.go Implements confirmed World deletion.
internal/cmd/world_test.go Tests confirmation and endpoint routing.
internal/tui/mail.go Blocks email actions on World posts.
internal/tui/mail_test.go Tests TUI action rejection.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/cmd/box.go
Comment thread README.md Outdated
Comment thread skills/hey/SKILL.md
Comment thread internal/cmd/posting_kind.go
Copilot AI review requested due to automatic review settings August 19, 2026 18:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (2)

internal/cmd/help.go:20

  • world is still rendered under the EMAIL heading even though this change establishes that HEY World posts are published content and that their actions are separate from email. Put this command in a non-email/HEY World category so root help communicates the same boundary as the command validation.
		names:   []string{"boxes", "box", "search", "contacts", "threads", "attachments", "compose", "reply", "forward", "drafts", "seen", "unseen", "move", "trash", "spam", "ignore", "stop-ignoring", "world"},

internal/cmd/box.go:30

  • The detailed description now says this command returns both email and World items, but its Short text and --limit help still call every result a thread. Those strings drive root/subcommand help and preserve the misleading email-only description this PR is intended to remove; update them to use “items” or explicitly mention both kinds, along with the help expectation.
		Long:  "List email threads and HEY World posts in a box. Each kind is counted separately. Accepts a box name (imbox, feedbox, etc.) or numeric ID.",

Copilot AI review requested due to automatic review settings August 19, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (1)

internal/cmd/box.go:137

  • The new Item column still renders resolvePostingTopicID(posting), so email rows show the topic ID while World rows fall back to the box item ID. These IDs can differ, and the newly documented seen/move/trash commands require the box item ID, so copying an email's displayed “Item” value can target the wrong resource. Render posting.Id consistently and expose the topic ID in a separately labeled column if the read workflow still needs it.
		fmt.Sprintf("%d", resolvePostingTopicID(posting)),

Copilot AI review requested due to automatic review settings August 19, 2026 19:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (7)

internal/cmd/seen.go:77

  • The new guard only works when --kind is supplied, but the built-in unseen help examples still omit it. Update these examples so copied commands preserve the item-kind boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each email thread as unseen/unread.",

internal/cmd/seen.go:23

  • The new guard only works when --kind is supplied, but the built-in seen help examples still demonstrate calls without it. This can lead users to copy the compatibility form and bypass the World-post boundary; align these examples with the README by passing --kind topic.

This issue also appears on line 77 of the same file.

			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each email thread as seen/read.",

internal/cmd/trash.go:23

  • The new guard only works when --kind is supplied, but hey trash --help still demonstrates commands without it. Add --kind topic so the built-in examples do not teach callers to bypass the World-post check.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Shared threads lose your access rather than being deleted for everyone.",

internal/cmd/spam.go:23

  • The new guard only works when --kind is supplied, but hey spam --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each thread as spam and removes it from the current box.",

internal/cmd/ignore.go:23

  • The new guard only works when --kind is supplied, but hey ignore --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Ignored threads remain in their box and can be restored with hey stop-ignoring.",

internal/cmd/stop_ignoring.go:23

  • The new guard only works when --kind is supplied, but hey stop-ignoring --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Reverses hey ignore for each thread.",

internal/cmd/move.go:33

  • The built-in move examples still omit --kind, even though this new annotation says callers should preserve it and the README examples now do so. Since omission bypasses the World-post guard, include --kind topic in all three help examples.
			"agent_notes": "Accepts box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. --to accepts a box name, kind, or ID. Use HEY's scheduled Bubble Up flow for Bubble Up.",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants